{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# What is a Scenario?\n",
    "\n",
    "A scenario is a set of parameters that define a market condition. Those parameters drive the factor returns that define\n",
    "that scenario, and we can then use those factor returns, along with the current factor exposures of a portfolio,\n",
    "to calculate the theoretical factor performance.\n",
    "\n",
    "What Types of Scenarios Exist?\n",
    "\n",
    "## Custom Factor Shocks\n",
    "\n",
    "This type of scenario shocks explicitly defined risk model factors up or down a certain percent. These scenarios must be risk-model specific and have two variations:\n",
    "\n",
    "1. **No Propagation**: This means the factors are shocked exactly as specified\n",
    "2. **Propagation**: all the factor shocks defined in the scenario are applied normally, but we also shock all other factors by a calculable amount as defined by the correlation between that factor and the factors that are shocked\n",
    "\n",
    "### How do I create a custom factor shock scenario?\n",
    "\n",
    "Let's create a custom factor shock scenario in which the Value factor in the global Axioma risk model rises by 5%,\n",
    "the Growth factor moves down by -5%, and the Medium-Term Momentum drops by -2%.\n",
    "\n",
    "#### I. Initialize a GsSession\n",
    "\n",
    "The initial step is to import all required modules and initialize a GsSession with your application ID and secret."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [],
   "source": [
    "from gs_quant.session import GsSession, Environment\n",
    "from gs_quant.markets.scenario import FactorScenario, FactorShockParameters, FactorShock, FactorScenarioType, \\\n",
    "    HistoricalSimulationParameters\n",
    "from gs_quant.entities.entity import ScenarioCalculationMeasure\n",
    "from gs_quant.markets.portfolio_manager import PortfolioManager\n",
    "from gs_quant.entities.entitlements import Entitlements, EntitlementBlock, User\n",
    "import datetime as dt\n",
    "\n",
    "GsSession.use(Environment.PROD, client_id=None, client_secret=None)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### II. Define custom factor shocks parameters\n",
    "\n",
    "Next, we define the set of parameters that encapsulate the key components of our custom factor shock scenario:\n",
    " - A valid risk model ID (see [full list of available risk models here](https://marquee.gs.com/s/discover/data-services/catalog?Category=Factor+Risk+Model)).\n",
    " - A set of factors and their corresponding shocks in %, defined as a list of `FactorShock` object.\n",
    " - Whether these shocks are propagated according to the correlation of factors in the risk model\n",
    "\n",
    "These three components will be encapsulated in a `FactorShockParameters` object. You make take a quick look at [historical factor returns](https://developer.gs.com/p/docs/services/risk/factor-models/get-factor-model-data/#:~:text=Get%20All%20Factor%20Returns) to guide you in\n",
    "determining factor shocks. Below, we are defining two sets of factor shock parameters with similar attributes\n",
    "except for the `propagate_shocks` component."
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [],
   "source": [
    "risk_model_id = \"AXIOMA_AXWW4M\"\n",
    "factor_1 = \"Value\"\n",
    "factor_2 = \"Growth\"\n",
    "factor_3 = \"Medium-Term Momentum\"\n",
    "\n",
    "factor_shocks = [\n",
    "    FactorShock(factor=factor_1, shock=5),\n",
    "    FactorShock(factor=factor_2, shock=-5),\n",
    "    FactorShock(factor=factor_3, shock=-2)\n",
    "]\n",
    "\n",
    "\n",
    "factor_shock_parameters_no_propagation = FactorShockParameters(factor_shocks=factor_shocks,\n",
    "                                                               risk_model=risk_model_id,\n",
    "                                                               propagate_shocks=False)\n",
    "\n",
    "factor_shock_parameters_with_propagation = FactorShockParameters(factor_shocks=factor_shocks,\n",
    "                                                                 risk_model=risk_model_id,\n",
    "                                                                 propagate_shocks=True)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### III. Set Scenario entitlements\n",
    "\n",
    "By default, an application will have all entitlement permissions to a scenario it creates. If you would like\n",
    "to share the scenario with other Marquee users at your firm or other applications, you will need to specify them in the\n",
    " `entitlements` attribute of the scenario. Let's walk through how we convert a list of admin, edit and viewer emails\n",
    " into an `Entitlements` object:"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [],
   "source": [
    "admin_emails = [\"ADMIN EMAILS\"]\n",
    "edit_emails = [\"EDIT EMAILS\"]\n",
    "view_emails = [\"VIEW EMAILS\"]\n",
    "\n",
    "admin_entitlements = EntitlementBlock(users=User.get_many(emails=admin_emails))\n",
    "edit_entitlements = EntitlementBlock(users=User.get_many(emails=edit_emails))\n",
    "view_entitlements = EntitlementBlock(users=User.get_many(emails=view_emails))\n",
    "\n",
    "scenario_entitlements = Entitlements(\n",
    "    view=view_entitlements,\n",
    "    edit=edit_entitlements,\n",
    "    admin=admin_entitlements\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### IV. Create a custom factor shock scenario\n",
    "\n",
    "Now we are ready to create a factor shock scenario. We will need:\n",
    "\n",
    "- A name for the scenario\n",
    "- The type of the scenario. Since we are creating a factor shock scenario, the type will be `FactorScenarioType.Factor_Shock`\n",
    "- The parameters of the scenario\n",
    "- Scenario entitlements\n",
    "- A description for the scenario\n",
    "\n",
    "Below, we will create two scenarios: one factor shock scenario with no propagation, the second one with propagation."
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [],
   "source": [
    "factor_shock_scenario_no_propagation_name = f\"Sample factor shock scenario with {risk_model_id} with no propagation\"\n",
    "factor_shock_scenario_no_propagation = FactorScenario(name=factor_shock_scenario_no_propagation_name,\n",
    "                                                      type=FactorScenarioType.Factor_Shock,\n",
    "                                                      parameters=factor_shock_parameters_no_propagation,\n",
    "                                                      description=f\"Sample custom shock scenario with {risk_model_id}\",\n",
    "                                                      entitlements=scenario_entitlements)\n",
    "factor_shock_scenario_no_propagation.save()\n",
    "print(factor_shock_scenario_no_propagation)\n",
    "\n",
    "factor_shock_scenario_propagation_name = f\"Sample factor shock scenario with {risk_model_id} with propagation\"\n",
    "factor_shock_scenario_with_propagation = FactorScenario(name=factor_shock_scenario_propagation_name,\n",
    "                                                        type=FactorScenarioType.Factor_Shock,\n",
    "                                                        parameters=factor_shock_parameters_with_propagation,\n",
    "                                                        description=f\"Sample custom shock scenario with {risk_model_id}\",\n",
    "                                                        entitlements=scenario_entitlements)\n",
    "factor_shock_scenario_with_propagation.save()\n",
    "print(factor_shock_scenario_with_propagation)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Historical Factor Scenario\n",
    "\n",
    "In a historical factor scenario, the aim is to replicate the market conditions during a significant or\n",
    "topical historical event and estimate the impact on your portfolio today. The first step is to define the time period\n",
    " of the historical event. Then, factor returns across the time period are geometrically aggregated, and these aggregated\n",
    " returns are the factor shocks that will be used to derive the estimated impact on the performance of your portfolio.\n",
    "\n",
    "\n",
    "### How do I create a historical factor scenario?\n",
    "\n",
    "Similar to factor shock scenarios, we will need to provide:\n",
    "- A name for the scenario\n",
    "- The type of the scenario. In this case, the scenario type is `FactorScenarioType.Factor_Historical_Simulation`\n",
    "- The parameters of the scenario\n",
    "- Scenario entitlements\n",
    "- A description for the scenario\n",
    "\n",
    "The parameters are defined in a `HistoricalSimulationParameters` object and will define the time\n",
    "period of the historical simulation scenario:\n",
    "\n",
    "- Start Date: The start date of the historical event simulation period\n",
    "- End Date: The end date of the historical event simulation period.\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [],
   "source": [
    "start_date = dt.date(2023, 1, 1)\n",
    "end_date = dt.date(2024, 1, 1)\n",
    "\n",
    "date_range_parameters = HistoricalSimulationParameters(start_date=start_date, end_date=end_date)\n",
    "historical_scenario_name = f\"Example historical simulation scenario from \" \\\n",
    "                           f\"{start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}\"\n",
    "historical_replay_scenario = FactorScenario(name=historical_scenario_name,\n",
    "                                            type=FactorScenarioType.Factor_Historical_Simulation,\n",
    "                                            parameters=date_range_parameters,\n",
    "                                            description=f\"Sample historical simulation scenario from {start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}\",\n",
    "                                            entitlements=scenario_entitlements)\n",
    "\n",
    "historical_replay_scenario.save()\n",
    "print(historical_replay_scenario)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## How do I get my scenarios or scenarios that are shared with me?\n",
    "\n",
    "You can get saved scenarios that you created or that were shared with you:\n",
    "- By its unique Marquee ID\n",
    "- By its name\n",
    "- By applying filters such as `risk_model`, `type` of the scenario, the `shocked_factors`, or whether the shocks are propagated\n",
    "- For a historical simulation scenario, you can filter by a `start_date` and `end_date`."
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [],
   "source": [
    "# Get by id\n",
    "scenario_by_id = FactorScenario.get(historical_replay_scenario.id)\n",
    "\n",
    "# Get all my factor Shock scenarios (and those that are shared with me) with risk model AXIOMA_AXWW4M and whose\n",
    "# factor shocks are propagated to all factors\n",
    "many_scenarios = FactorScenario.get_many(risk_model=risk_model_id,\n",
    "                                         propagated_shocks=True,\n",
    "                                         type=FactorScenarioType.Factor_Shock)\n",
    "# Get all my factor Shock scenarios (and those that are shared with me) with risk model AXIOMA_AXWW4M that shocks the\n",
    "# Value factor\n",
    "many_scenarios = FactorScenario.get_many(risk_model=risk_model_id,\n",
    "                                         shocked_factors=[\"Value\"],\n",
    "                                         type=FactorScenarioType.Factor_Shock)\n",
    "\n",
    "# Get all my historical simulation scenarios that are within the requested start and end date\n",
    "historical_simulation_scenarios = FactorScenario.get_many(type=\"Factor Historical Simulation\",\n",
    "                                                          start_date=dt.date(2023, 1, 1),\n",
    "                                                          end_date=dt.date(2024, 1, 1))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## How do I get GS pre-canned scenarios?\n",
    "\n",
    "To get GS pre-canned scenarios, you can additionally filter by the tag \"GS\". See below for some examples"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [],
   "source": [
    "# Get 3 factor shocks scenarios with risk model AXIOMA_AXWW4M that propagate factor shocks\n",
    "pre_canned_factor_shock_scenarios = FactorScenario.get_many(risk_model=risk_model_id,\n",
    "                                                            propagated_shocks=True,\n",
    "                                                            type=FactorScenarioType.Factor_Shock,\n",
    "                                                            tags=[\"GS\"],\n",
    "                                                            limit=3)\n",
    "print(pre_canned_factor_shock_scenarios)\n",
    "\n",
    "# Get 3 historical simulation that are within selected start and end date\n",
    "pre_canned_historical_simulation_scenarios = FactorScenario.get_many(type=\"Factor Historical Simulation\",\n",
    "                                                                     start_date=dt.date(2010, 1, 1),\n",
    "                                                                     end_date=dt.date(2024, 1, 1),\n",
    "                                                                     tags=[\"GS\"],\n",
    "                                                                     limit=3)\n",
    "print(pre_canned_historical_simulation_scenarios)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Running scenario(s) on a portfolio\n",
    "\n",
    "To see the estimated impact of scenarios on your portfolio, run the `get_factor_scenario_analytics` function in the\n",
    "`PortfolioManager` class, which is the interface for managing your portfolios in Marquee.\n",
    "\n",
    "A scenario calculation request requires the following components:\n",
    "\n",
    "- A date: date on which to run a scenario. We will run the scenario(s) on your portfolio holdings as of this date.\n",
    "- Scenarios: List of scenarios to run. Can either be a list of unique Marquee IDs, or a scenario object itself.\n",
    "- Risk Model: The risk model to run a scenario with.\n",
    "- Measures: Metrics to return, which include:\n",
    "    1. Total portfolio estimated factor PnL\n",
    "    2. Total portfolio PnL by GICS sector & industry\n",
    "    3. Total portfolio PnL by region\n",
    "    4. Total portfolio PnL by the direction (LONG/SHORT) of your portfolio holdings,\n",
    "    5. Estimated performance of each asset in your portfolio."
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "portfolio_id = \"PORTFOLIO ID\"\n",
    "pm = PortfolioManager(portfolio_id)\n",
    "\n",
    "scenario_analytics = pm.get_factor_scenario_analytics(scenarios=[historical_replay_scenario],\n",
    "                                                      date=dt.date(2024, 4, 10),\n",
    "                                                      measures=[ScenarioCalculationMeasure.SUMMARY,\n",
    "                                                                ScenarioCalculationMeasure.ESTIMATED_FACTOR_PNL,\n",
    "                                                                ScenarioCalculationMeasure.ESTIMATED_PNL_BY_SECTOR,\n",
    "                                                                ScenarioCalculationMeasure.ESTIMATED_PNL_BY_REGION,\n",
    "                                                                ScenarioCalculationMeasure.ESTIMATED_PNL_BY_DIRECTION,\n",
    "                                                                ScenarioCalculationMeasure.ESTIMATED_PNL_BY_ASSET],\n",
    "                                                      risk_model=risk_model_id)\n",
    "summary = scenario_analytics.get('summary')\n",
    "factor_pnl = scenario_analytics.get('factorPnl')\n",
    "sector_aggregations = scenario_analytics.get('bySectorAggregations')\n",
    "region_aggregations = scenario_analytics.get(\"byRegionAggregations\")\n",
    "by_asset_aggregations = scenario_analytics.get('byAsset')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Run scenario(s) on a basket\n",
    "\n",
    "We can also run one or multiple scenarios on an existing equity custom basket and pull scenario analytics data."
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "from gs_quant.markets.baskets import Basket\n",
    "\n",
    "basket_ticker = \"BASKET_TICKER\"\n",
    "basket = Basket.get(basket_ticker)\n",
    "\n",
    "basket_scenario_analytics = basket.get_factor_scenario_analytics(\n",
    "    scenarios=[factor_shock_scenario_no_propagation, factor_shock_scenario_with_propagation, historical_replay_scenario],\n",
    "    date=dt.date(2024, 4, 1),\n",
    "    measures=[ScenarioCalculationMeasure.SUMMARY, ScenarioCalculationMeasure.ESTIMATED_FACTOR_PNL,\n",
    "              ScenarioCalculationMeasure.ESTIMATED_PNL_BY_SECTOR,\n",
    "              ScenarioCalculationMeasure.ESTIMATED_PNL_BY_REGION,\n",
    "              ScenarioCalculationMeasure.ESTIMATED_PNL_BY_DIRECTION,\n",
    "              ScenarioCalculationMeasure.ESTIMATED_PNL_BY_ASSET],\n",
    "   risk_model=risk_model_id)\n",
    "\n",
    "summary = basket_scenario_analytics.get('summary')\n",
    "factor_pnl = basket_scenario_analytics.get('factorPnl')\n",
    "sector_aggregations = basket_scenario_analytics.get('bySectorAggregations')\n",
    "region_aggregations = basket_scenario_analytics.get(\"byRegionAggregations\")\n",
    "by_asset_aggregations = basket_scenario_analytics.get('byAsset')\n",
    "\n",
    "\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}